home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-03-27 | 5.7 KB | 190 lines | [TEXT/MPS ] |
- program drag;
-
- USES {$LOAD pinterfaces.dump}
- MemTypes,QuickDraw,OsIntf,PasLibIntf,ToolIntf,
- PackIntf,IntEnv,CursorCtl;
-
- var myPic : PicHandle;
- myRect : Rect;
- oldPort: GrafPtr;
-
- procedure DragIt( thePicture : PicHandle );
- var
- offScreenBits, {entire screen image}
- underBits, {bits obscured by picture}
- pictureBits : BitMap; {the picture}
-
- updateRegion, {new position of picture
- plus last position}
- thePictureRgn : RgnHandle; {use this for masking}
-
- wMgrPort,
- oldPort,
- workPort : GrafPtr;
-
- lastRect, {this + dragRect => updateRegion}
- otherUpdateRect, {updateRect clipped to include only bits onscreen}
- updateRect, {union of dragRect and lastRect}
- dragRect, {size of the picture & centered over cursor}
- tempBounds : Rect; {used in creating bitmaps}
-
- mousePt, {used to position dragRect}
- otherMousePt, {used to see if cursor has moved}
- testPt : Point; {used to see if cursor has moved}
-
- synchCount : longint; {wait for TickCount to change before drawing}
-
- begin
- {remember where we are then do all the work in the wMgrPort}
- GetPort( oldPort );
- GetWMgrPort( wMgrPort );
-
- {try to allocate and erase the following bitmaps
- - pictureBits holds the bitmap to display
- - underBits holds the bits obscured by the picture
- - offScreenBits holds the entire screen's image
- }
- {create a bitmap for the picture the size of the picture frame}
- tempBounds := thePicture^^.picFrame;
- with pictureBits, tempBounds do
- begin
- rowBytes := ((right - left + 15) DIV 16) * 2;
- baseAddr := NewPtr(rowBytes * (bottom - top));
- bounds := tempBounds;
- if MemError <> noErr then baseAddr := nil;
- if baseAddr = nil then IEExit(1);
- end;
- {home tempBounds before setting up underBits}
- with tempBounds do OffSetRect( tempBounds, -left, -top );
- with underBits, tempBounds do
- begin
- rowBytes := ((right - left + 15) DIV 16) * 2;
- baseAddr := NewPtr(rowBytes * (bottom - top));
- bounds := tempBounds;
- if MemError <> noErr then baseAddr := nil;
- if baseAddr = nil then IEExit(1);
- end;
- {now make an offscreen bitmap to hold the whole screen}
- tempBounds := screenBits.bounds;
- with offScreenBits, tempBounds do
- begin
- rowBytes := ((right - left + 15) DIV 16) * 2;
- baseAddr := NewPtr(rowBytes * (bottom - top));
- bounds := tempBounds;
- if MemError <> noErr then baseAddr := nil;
- if baseAddr = nil then IEExit(1);
- end;
-
- workPort := GrafPtr( NewPtr( sizeof(GrafPort) ) );
- if workPort = nil then IEExit(1);
-
- {clear out the bitmap for the picture}
- OpenPort( workPort );
- SetPortBits( pictureBits );
- EraseRect( pictureBits.bounds );
-
- {create the region to update with}
- updateRegion := NewRgn;
-
- {draw the picture into pictureBits & create thePictureRgn}
- thePictureRgn := NewRgn;
- OpenRgn;
- DrawPicture( thePicture, thePicture^^.picFrame );
- CloseRgn( thePictureRgn );
- DrawPicture( thePicture, thePicture^^.picFrame );
-
- {the bounding rect to track with the cursor}
- dragRect := pictureBits.bounds;
-
- {copy the screen}
- CopyBits( screenBits, offScreenBits, screenBits.bounds,
- offScreenBits.bounds, srcCopy, nil );
-
- SetPort( wMgrPort );
- SetRect( lastRect, 0,0,0,0 );
-
- while button do
- begin
- GetMouse( mousePt );
- SystemTask;
- otherMousePt := mousePt;
- {home the region and the rect}
- OffSetRgn( thePictureRgn, -dragRect.left, -dragRect.top );
- OffSetRect( dragRect, -dragRect.left, -dragRect.top );
- {center the object over the cursor}
- {calculate mousePt here because we know the rect is home'd}
- mousePt.h := mousePt.h - dragRect.right div 2;
- mousePt.v := mousePt.v - dragRect.bottom div 2;
- OffSetRect( dragRect, mousePt.h, mousePt.v );
- OffSetRgn( thePictureRgn, mousePt.h, mousePt.v );
-
- {save bits underneath}
- {remove any part of dragRect which is off the screen}
- if SectRect( screenBits.bounds, dragRect, updateRect ) then {};
- otherUpdateRect := updateRect;
- with otherUpdateRect do
- OffSetRect( otherUpdateRect, -left, -top );
- CopyBits( offScreenBits, underBits, updateRect, otherUpdateRect,
- srcCopy,nil );
- {mask out shape of my object}
- CopyBits( pictureBits, offScreenBits, pictureBits.bounds, dragRect,
- notSrcBic, thePictureRgn );
- {draw my object}
- CopyBits( pictureBits, offScreenBits, pictureBits.bounds, dragRect,
- srcOr, thePictureRgn );
-
- {wait for just the right moment}
- synchCount := TickCount;
- repeat until TickCount <> synchCount;
- {update what was on there plus the new position for the object}
- UnionRect( dragRect, lastRect, updateRect );
- RectRgn( updateRegion, updateRect );
- {put it on the screen}
- if SectRect( screenBits.bounds, updateRect, updateRect ) then {};
- RectRgn( updateRegion, updateRect );
- CopyBits( offScreenBits, screenBits, updateRect, updateRect,
- srcCopy, updateRegion );
-
- {wait until the mouse is moved}
- repeat GetMouse( testPt );
- until not EqualPt( testPt, otherMousePt ) or not button;
- {restore bits underneath}
- {remove any part of dragRect which is off the screen}
- if SectRect( dragRect, screenBits.bounds, updateRect ) then {};
- CopyBits( underBits, offScreenBits,
- otherUpdateRect, updateRect, srcCopy, nil );
- lastRect := dragRect;
- end; {while button}
-
- {tidy up}
- CopyBits( offScreenBits, screenBits, offScreenBits.bounds, screenBits.bounds,
- srcCopy, nil );
- SetPort( oldPort );
- ClosePort( workPort );
- DisposPtr( Pointer(workPort) );
- DisposPtr( pictureBits.baseAddr );
- DisposPtr( underBits.baseAddr );
- DisposPtr( offScreenBits.baseAddr );
- DisposHandle( Handle(thePictureRgn) );
- DisposHandle( Handle(updateRegion) );
-
- end; {DragIt}
-
- begin{main}
- InitGraf(@thePort);
- GetWMgrPort( oldPort );
- SetPort( oldPort );
-
- ClipRect( screenBits.bounds );
- myPic := PicHandle(GetResource('PICT', 128));
-
- InitCursor;
- repeat until button;
-
- HideCursor;
- DragIt( myPic );
- ShowCursor;
-
- IEExit(0);
- end.
-